import { store, IPageMeta } from "./store";
import { createMetaObject, IMeta } from "./meta";
import $cmpnt, { IPageCmpnt, isContainer, ICmpnt, IContainerField, isWidget, isPage } from "xcore/cmpnt";
import { enums } from "../enum";
import $provider from "../provider/index";
import { reactive } from "vue";

let excludeExport: string[] = ["meta", "containers"]

class _func {
  setPage(page: IPageMeta): void {
    store.page = page;
    this.activate(page);
  }
  bindPage(page: IPageCmpnt, data: IMeta | any): IPageMeta {
    page.meta = createMetaObject(page, data);
    let npage = page as IPageMeta;
    return npage
  }
  exportCmpnt(page: ICmpnt): any {
    type JsonObject = { [key: string]: any };

    function removeUnderscoreAndCtlAttributes(obj: JsonObject): JsonObject {
      if (Array.isArray(obj)) {
        return obj.map(item => removeUnderscoreAndCtlAttributes(item));
      } else if (typeof obj === 'object' && obj !== null) {
        const newObj: JsonObject = {};
        for (const key in obj) {
          if (obj.hasOwnProperty(key)) {
            if (typeof obj[key] === 'function') {
              continue;
            } if (key === 'children' && Array.isArray(obj[key])) {
              newObj[key] = removeUnderscoreAndCtlAttributes(obj[key]);
            } else if (key.startsWith('_') || excludeExport.includes(key)) {
              continue;
            } else {
              newObj[key] = removeUnderscoreAndCtlAttributes(obj[key]);
            }
          }
        }
        return newObj;
      } else {
        return obj;
      }
    }
    return removeUnderscoreAndCtlAttributes(page);
  }


  getById(id: string): ICmpnt | null {
    return store.page ? this.find(id).element : null;
  }

  // 添加组件
  addCmpnt(cmpnt: ICmpnt, cmpnts?: any[]) {
    //直接添加组件
    if (cmpnts) {
      cmpnts.push(cmpnt)
      this.activate(cmpnt);
      console.warn("添加组件到容器", cmpnts);
      return;
    }

    // 激活组件中添加容器或组件
    if (!store.conf.selected?.id) {
      console.warn("未找到激活组件")
      return;
    }
    const current = this.find(store.conf.selected?.id) // 尝试从激活的组件中获取容器
    if (isContainer(current.element) || isPage(current.element)) {
      current.element.children.push(cmpnt)
      this.activate(cmpnt);
      console.log("添加组件到容器", current.element);
      return;
    }
    if (isWidget(current.element)) {
      for (let i = 0; i < current.parents.length; i++) {
        if (isContainer(current.parents[i])) {
          current.parents[i].children.push(cmpnt)
          this.activate(cmpnt);
          console.log("添加组件到容器", current.parents[i]);
          return;
        }
      }
    }
    console.warn("未找到激活组件的容器", current.element);
  };

  // 函数重载声明
  findParent(id: string, category: string): ICmpnt | undefined {
    return this.findParentBy(id, category, 'category');
  }
  findParentBy(id: string, value: string, by?: 'category' | 'cmpntName', stopAtPage: boolean = false): ICmpnt | undefined {
    // 如果没有传递 by 参数，默认按 category 查找
    const searchBy = by || 'category';
    const ele = this.find(id);

    // 如果未找到目标元素或没有父级，直接返回 undefined
    if (!ele.element || !ele.parents) return undefined;
    if (searchBy === 'category' && ele.element.ctl?.group.toLowerCase() === value.toLowerCase()) {
      return ele.element as ICmpnt;
    } else if (searchBy === 'cmpntName' && ele.element.ctl?.name.toLowerCase() === value.toLowerCase()) {
      return ele.element as ICmpnt;
    }

    // 遍历父级列表，查找符合条件的组件
    for (let i = ele.parents.length - 1; i >= 0; i--) {
      const parent = ele.parents[i];

      // 如果 stopAtPage 为 true，并且当前父级的 category 是 'page'，则停止查找并返回该组件
      if (stopAtPage && parent.category.toLowerCase() === 'page') {
        return parent as ICmpnt;
      }

      // 根据 searchBy 参数决定比较的字段
      if (searchBy === 'category' && parent.ctl?.group.toLowerCase() === value.toLowerCase()) {
        return parent as ICmpnt;
      } else if (searchBy === 'cmpntName' && parent.ctl?.name.toLowerCase() === value.toLowerCase()) {
        return parent as ICmpnt;
      }
    }

    // 如果没有找到符合条件的组件，返回 undefined
    return undefined;
  }

  getCmpntRef(id: string): any | undefined {
    return store.page.meta.getRef(id)
  }
  find(id: string): { parents: any[]; cmpnts: any[], element: any; index: number } {
    const _find = (id: string, lst: any[], parents: any[] = []): { parents: any[]; cmpnts: any[]; element: any; index: number } => {
      let current: { parents: any[]; cmpnts: any[]; element: any; index: number } = { parents: [], cmpnts: [], element: null, index: -1 };

      lst.forEach((e, index) => {
        if (current.element) return; // 如果已经找到目标元素，直接返回

        // 如果当前元素的 id 匹配
        if (e.id === id) {
          current.element = e;
          current.parents = parents;
          current.index = index;
          current.cmpnts = lst
          return;
        }

        // 递归查找 children
        if (e.children && e.children.length > 0) {
          current = _find(id, e.children, [...parents, e]);
          if (current.element) return; // 如果在 children 中找到目标元素，直接返回
        }

        // 递归查找以 Cmpnt 结尾的属性（如 xxxCmpnt）
        for (const key in e) {
          if (key.toLowerCase().endsWith('cmpnts') && Array.isArray(e[key])) {
            current = _find(id, e[key], [...parents, e]);
            if (current.element) return; // 如果在 xxxCmpnt 中找到目标元素，直接返回
          }
        }

        // 递归查找以 Fields 结尾的属性（如 xxxFields）中的 cmpnts
        for (const key in e) {
          if (key.toLowerCase().endsWith('fields') && Array.isArray(e[key])) {
            for (const field of e[key]) {
              if (field.cmpnts && Array.isArray(field.cmpnts)) {
                current = _find(id, field.cmpnts, [...parents, e]);
                if (current.element) return; // 如果在 cmpnts 中找到目标元素，直接返回
              }
            }
          }
        }

        // 递归查找 xxxGroup,props 内部的嵌套结构
        for (const key in e) {
          if ((key.toLowerCase().endsWith('group') || key == "props") && typeof e[key] === 'object') {
            current = _find(id, [e[key]], [...parents, e]); // 将 xxxGroup 作为数组传入
            if (current.element) return; // 如果在 xxxGroup 中找到目标元素，直接返回
          }
        }
      });

      return current;
    };

    return _find(id, [store.page]);
  }
  // 激活组件
  activate(cmpnt: ICmpnt) {
    store.conf.selected = cmpnt;
  };

  // 取消激活
  unactive() {
    this.activate(store.page);
  };

  // 清空组件
  clear() {
    if (!store.page || !store.page) return;
    store.page.children.length = 0;
    this.activate(store.page);
  };

  removeCmpnt(cmpnt: ICmpnt) {
    if (!cmpnt) return;

    // 查找目标组件及其父级信息
    const { parents, cmpnts, index } = this.find(cmpnt.id);

    // 如果找到了目标组件
    if (index !== -1 && cmpnts) {
      // 从父级列表中删除目标组件
      cmpnts.splice(index, 1);
    }

    // 删除数据
    if (parents && parents.length > 0) {
      store.page.meta.remove(parents[0].id);
    }

    // 如果当前选中的组件是被删除的组件，取消激活状态
    if (store.conf.selected?.id === cmpnt.id) {
      this.unactive();
    }
  }

  // 替换组件
  replace(cmpnt: ICmpnt, newCmpnt: ICmpnt): boolean {
    if (!cmpnt || !newCmpnt) return false;

    // 查找目标组件及其父级信息
    const { parents, cmpnts, index } = this.find(cmpnt.id);

    // 如果未找到目标组件或父级信息，返回 false
    if (index === -1 || !cmpnts || !parents || parents.length === 0) return false;

    // 替换目标组件
    newCmpnt.props.dbField = cmpnt.props.dbField; // 保留原组件的 dbField
    cmpnts[index] = newCmpnt; // 直接替换组件

    return true;
  }

  // 创建用户组件
  createCmpnt(item: IContainerField): any[] {
    if (item.cmpnts) return item.cmpnts
    item.cmpnts = reactive([])

    $provider.meta.getMetaColumn(item.fieldId).then((metaColumn: any) => {
      const cmpntType = enums.joinType("cmpnt", enums.getValueChar(metaColumn.type));
      // 根据数据库字段类型获取组件名称列表
      const cmpntNames = enums.getItems(cmpntType, metaColumn.source)?.map((item: any) => item.value + "") || [];
      if (!cmpntNames || cmpntNames.length === 0)
        return []; // 如果没有找到对应的组件名称，返回空数组
      let cmpntName = cmpntNames[0];

      // 根据组件名称获取组件实例
      const cmpnt = $cmpnt.find(cmpntName)?.clone();
      if (!cmpnt) return [];
      // 设置组件属性
      cmpnt.props.placeholder = item.title;
      cmpnt.valueKey = item.name;
      cmpnt.props.dbField = {
        title: metaColumn.title,
        name: metaColumn.name,
        fieldId: item.fieldId
      }
      if (item.cmpnts) {
        item.cmpnts.length = 0;
        item.cmpnts?.push(cmpnt);
      }
    });
    return item.cmpnts || []
  }
}
const func = new _func();
export { func };
